﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ext = GSPatEditor.Simulator.ActorReferencePointExt;

namespace GSPatEditor.Pat.Effect.Effects
{
    class ClearLabel : EffectBase
    {
        public override void Generate(StringBuilder sb)
        {
            throw new NotImplementedException();
        }

        public override void Simulate(Simulator.Actor actor)
        {
            Simulator.ActorActions.ClearLabel(actor);
        }
    }
    class SetMotion : EffectBase
    {
        public int AnimationName { get; set; }
        private Animation animation;

        //public void Init(NormalAction parent)
        //{
        //    animation = parent.Project.GetAnimationByName(AnimationName);
        //}

        public override void Generate(StringBuilder sb)
        {
            throw new NotImplementedException();
        }

        public override void Simulate(Simulator.Actor actor)
        {
            actor.SetMotion(animation, 0);
        }
    }
    class ReduceSpeedRatio : EffectBase
    {
        public float RatioX { get; set; }
        public float RatioY { get; set; }
        
        public override void Generate(StringBuilder sb)
        {
            throw new NotImplementedException();
        }

        public override void Simulate(Simulator.Actor actor)
        {
            actor.VX *= RatioX;
            actor.VY *= RatioY;
        }
    }
    class FallCancel : EffectBase
    {
        public override void Generate(StringBuilder sb)
        {
            throw new NotImplementedException();
        }

        public override void Simulate(Simulator.Actor actor)
        {
            actor.FallLabel = Simulator.ActorActions.BeginFall;
        }
    }
    class SitCancel : EffectBase
    {
        public override void Generate(StringBuilder sb)
        {
            throw new NotImplementedException();
        }

        public override void Simulate(Simulator.Actor actor)
        {
            actor.SitLabel = Simulator.ActorActions.BeginSit;
        }
    }
    class AdjustDirection : EffectBase
    {
        public override void Generate(StringBuilder sb)
        {
            throw new NotImplementedException();
        }

        public override void Simulate(Simulator.Actor actor)
        {
            //not supported in simulation
        }
    }
    class StopMoving : EffectBase
    {
        public float ReduceSpeed { get; set; }

        public override void Generate(StringBuilder sb)
        {
            throw new NotImplementedException();
        }

        public override void Simulate(Simulator.Actor actor)
        {
            if (Math.Abs(actor.VX) < ReduceSpeed)
            {
                actor.VX = 0;
            }
            else
            {
                actor.VX -= actor.VX > 0 ? ReduceSpeed : -ReduceSpeed;
            }
        }
    }
    class CreateActor : EffectBase
    {
        public int ActorName { get; set; }
        public int PointIndex { get; set; }
        private ActorGenerator generator;

        //public void Init(NormalAction parent)
        //{
        //    generator = parent.Project.GetActorGeneratorByName(ActorName);
        //}

        public override void Generate(StringBuilder sb)
        {
            throw new NotImplementedException();
        }

        public override void Simulate(Simulator.Actor actor)
        {
            if (PointIndex == -1)
            {
                actor.World.CreateActor(generator.SetupActor, actor.X, actor.Y);
            }
            else
            {
                float x, y;
                Ext.GetReferencePoint(actor, PointIndex, out x, out y);
                actor.World.CreateActor(generator.SetupActor, x, y);
            }
        }
    }
    class PlayerEndToFreeMove : EffectBase
    {
        public override void Generate(StringBuilder sb)
        {
            throw new NotImplementedException();
        }

        public override void Simulate(Simulator.Actor actor)
        {
            Simulator.ActorActions.PlayerEndToFreeMove(actor);
        }
    }
    class Rush : EffectBase
    {
        public override void Generate(StringBuilder sb)
        {
            throw new NotImplementedException();
        }

        public override void Simulate(Simulator.Actor actor)
        {
            //not supported yet
        }
    }
    class IncreaseSpeedX : EffectBase
    {
        public float CheckBefore { get; set; }
        public float Increase { get; set; }
        public float CheckAfter { get; set; }

        public override void Generate(StringBuilder sb)
        {
            throw new NotImplementedException();
        }

        public override void Simulate(Simulator.Actor actor)
        {
            if (CheckBefore != 0)
            {
                if (Math.Abs(actor.VX) > CheckBefore)
                {
                    return;
                }
            }
            actor.VX += Increase;
            if (CheckAfter != 0)
            {
                if (Math.Abs(actor.VX) > CheckAfter)
                {
                    actor.VX = actor.VX > 0 ? CheckAfter : -CheckAfter;
                }
            }
        }
    }
    class MotionContinue : EffectBase
    {
        public override void Generate(StringBuilder sb)
        {
            throw new NotImplementedException();
        }

        public override void Simulate(Simulator.Actor actor)
        {
            actor.SetMotion(actor.CurrentAnimation, actor.CurrentKeyFrameIndex + 1);
        }
    }
    class ClearCount : EffectBase
    {
        public override void Generate(StringBuilder sb)
        {
            throw new NotImplementedException();
        }

        public override void Simulate(Simulator.Actor actor)
        {
            actor.ActionCount = 0;
        }
    }
    class IncreaseCount : EffectBase
    {
        public override void Generate(StringBuilder sb)
        {
            throw new NotImplementedException();
        }

        public override void Simulate(Simulator.Actor actor)
        {
            ++actor.ActionCount;
        }
    }
    class IncreaseSpeedY : EffectBase
    {
        public float Increase { get; set; }
        public bool SetAirFlag { get; set; }
        public bool CreateSmoke { get; set; }

        public override void Generate(StringBuilder sb)
        {
            throw new NotImplementedException();
        }

        public override void Simulate(Simulator.Actor actor)
        {
            actor.VY += Increase;
            if (!actor.IsInAir)
            {
                if (CreateSmoke)
                {
                    throw new NotImplementedException();
                }
            }
            if (Increase < 0 && SetAirFlag)
            {
                actor.IsInAir = true;
            }
        }
    }
    class PlaySoundEffect : EffectBase
    {
        public int SEName { get; set; }
        private SoundEffect.SoundEffect se;

        //public void Init(NormalAction parent)
        //{
        //    se = parent.Project.SoundEffectResources.GetSoundEffectByName(SEName);
        //}

        public override void Generate(StringBuilder sb)
        {
            throw new NotImplementedException();
        }

        public override void Simulate(Simulator.Actor actor)
        {
            se.Play();
        }
    }

}
